package com.woniuxy.sale.config;

import com.alibaba.druid.pool.DruidDataSource;
import io.seata.rm.datasource.DataSourceProxy;
import org.apache.ibatis.session.SqlSessionFactory;
import org.mybatis.spring.SqlSessionFactoryBean;
import org.mybatis.spring.transaction.SpringManagedTransactionFactory;
import org.springframework.boot.context.properties.ConfigurationProperties;
import org.springframework.context.annotation.Bean;
import org.springframework.context.annotation.Configuration;
import org.springframework.context.annotation.Primary;
import org.springframework.core.io.support.PathMatchingResourcePatternResolver;

import javax.sql.DataSource;


@Configuration
public class DataSourceConfiguration {
    /*
     * @ConfigurationProperties用于application.yml中的配置信息
     * prefix：前缀定义了读取到application.yml中哪些属性，在创建完对象之后，在加入IOC
     * 容器里面之后会自动给该对象的属性赋值
     */
    @Bean
    @ConfigurationProperties(prefix = "spring.datasource")
    public DataSource druidDataSource(){
        DruidDataSource druidDataSource = new DruidDataSource();
        return druidDataSource;
    }
    /*
     * 设置DataSource代理，主要目的是让mybatis在获取datasource时获取到由druid代理的dataSource
     * 能够让seata管理到数据库的操作，实现分布式事务
     * 通过DataSourceProxy能在业务代码的事务提交时，seata通过这个切入点，来给TC发送RM的处理结果
     *
     * 当一个接口有2个不同实现时,使用@Autowired注解时会报
     * org.springframework.beans.factory.NoUniqueBeanDefinitionException异常信息
     * Primary用于高速spring在不知道该注入哪个bean时，优先使用选择该bean
     *
     * DataSourceProxy extends AbstractDataSourceProxy
     * AbstractDataSourceProxy implements javax.sql.DataSource
     *
     */
    @Primary
    @Bean("dataSource")
    public DataSourceProxy dataSource(DataSource druidDataSource){
        return new DataSourceProxy(druidDataSource);
    }

    /*
     * 创建SqlSessionFactory
     */
    @Bean
    public SqlSessionFactory sqlSessionFactory(DataSourceProxy dataSourceProxy)throws Exception{
        SqlSessionFactoryBean sqlSessionFactoryBean = new SqlSessionFactoryBean();
        //设置数据源   javax.sql.DataSource
        sqlSessionFactoryBean.setDataSource(dataSourceProxy);
        //加载mapper文件
        sqlSessionFactoryBean.setMapperLocations(new PathMatchingResourcePatternResolver()
                .getResources("classpath*:/mapper/*.xml"));
        //开启驼峰
        org.apache.ibatis.session.Configuration configuration = new org.apache.ibatis.session.Configuration();
        configuration.setMapUnderscoreToCamelCase(true);
        sqlSessionFactoryBean.setConfiguration(configuration);

        //设置事务工厂，用于创建事务
        sqlSessionFactoryBean.setTransactionFactory(new SpringManagedTransactionFactory());
        //创建工厂对象
        return sqlSessionFactoryBean.getObject();
    }
}